package com.tinem.platform.module.pojo.enums.security;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.tinem.platform.module.pojo.vo.error.SystemException;
import com.tinem.platform.module.starter.sdk.MessageCode;
import lombok.AllArgsConstructor;

import java.nio.charset.StandardCharsets;

/**
 * @author fzh
 * @version v1
 * @program: platform
 * @className EncryptionAlgorithm
 * @description 通过策略模式实现加密算法。
 * @site
 * @company
 * @create 2021-06-11 15:47
 */
@AllArgsConstructor
public enum EncryptionAlgorithm {
    /** AES 加密算法 */
    AES_ECB_PKCS5PADDING
    /** RSA 加密算法 */
    ,RSA
    ;

    /**
     * 加密
     * @param key
     * @param iv
     * @param ppk 私钥
     * @param body
     * @return
     */
    public String encrypt(String key,String iv,String ppk,String body){
        if(this == AES_ECB_PKCS5PADDING){
            byte[] k = SecureUtil.decode(key);
            SymmetricCrypto symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.AES, k);
            if(StrUtil.isNotBlank(iv)){
                symmetricCrypto.setIv(SecureUtil.decode(iv));
            }
            return symmetricCrypto.encryptBase64(body,StandardCharsets.UTF_8);
        }else if(this == RSA){
            cn.hutool.crypto.asymmetric.RSA rsa = new RSA(ppk,null);
            return rsa.encryptBase64(body,StandardCharsets.UTF_8, KeyType.PrivateKey);
        }else{
            throw new SystemException(MessageCode.ERROR_COMMONS_ENCRYPTION_TYPE);
        }

    }

    /**
     * 解密
     * @param key
     * @param iv
     * @param puk 公钥
     * @param body
     * @return
     */
    public String decrypt(String key, String iv, String puk, String body){
        if(this == AES_ECB_PKCS5PADDING){
            byte[] k = SecureUtil.decode(key);
            SymmetricCrypto symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.AES, k);
            if(StrUtil.isNotBlank(iv)){
                symmetricCrypto.setIv(SecureUtil.decode(iv));
            }
            return symmetricCrypto.decryptStr(body,StandardCharsets.UTF_8);
        }else if(this == RSA){
            cn.hutool.crypto.asymmetric.RSA rsa = new RSA(null,puk);
            return rsa.encryptBase64(body,StandardCharsets.UTF_8, KeyType.PublicKey);
        }else{
            throw new SystemException(MessageCode.ERROR_COMMONS_ENCRYPTION_TYPE);
        }
    }
}
